package io.iec.edp.caf.commons.runtime.config;

import io.iec.edp.caf.commons.runtime.CafEnvironment;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class ServiceUnitConfigService {

    private static Lock locker = new ReentrantLock();

    private static List<Map<String,String>> allSuInfo = new ArrayList<>();
    private static List<String> allSu = new ArrayList<>();
    private static String msuJsonConfig;
    private static String msuYamlConfig;
    private static boolean isInitialized = false;

    private static Log log = LogFactory.getLog(ServiceUnitConfigService.class);

    static public List<Map<String,String>> getAllSuInfo(){
        //首次获取进行初始化
        if(!isInitialized) {
            ensureInitialized();
        }
        return allSuInfo;
    }

    /**
     * 获得环境中所有su
     * @return
     */
    static public List<String> getAllSu(){
        //首次获取进行初始化
        if(!isInitialized) {
            ensureInitialized();
        }
        return allSu;
    }

    /**
     * 获得caf_serviceunit.json内容
     * @return
     */
    static public String getMsuJsonConfig(){
        if(!isInitialized){
            ensureInitialized();
        }
        return msuJsonConfig;
    }

    static public String getMsuYamlConfig(){
        if(!isInitialized){
            ensureInitialized();
        }
        return msuYamlConfig;
    }


    /**
     * 获取已启用的所有su信息
     * 如果需求的时机较早且不能依赖caf-su时，可以调用此方法
     * @return
     */
    static public List<String> getEnableSu(){

        List<String> enableSuList = new ArrayList<>();
        enableSuList = MsuConfigReader.getEnableSuListFromJson(getMsuJsonConfig(),getAllSu());


        return enableSuList;
    }


    /**
     *  初始化配置
     */
    static private void ensureInitialized(){
        try{
            locker.lock();
            loadAllMsu();
            loadJsonConfig();
            loadYamlConfig();
        }finally {
            isInitialized = true;
            locker.unlock();
        }
    }

    /**
     * 读取当前服务器下所有的su信息（包括未启用的）
     */
    static private void loadAllMsu(){
        String serverPath = CafEnvironment.getServerRTPath();
        getServiceUnitInfo(new File(serverPath));
    }

    /**
     * 读取caf_serviceunit.json文件内容
     */
    static private void loadJsonConfig(){
        String suConfigPath = CafEnvironment.getServerRTPath() + File.separator + "config" +
                File.separator + "runtime" + File.separator + "caf_serviceunits.json";

        msuJsonConfig = MsuConfigReader.readToBuffer(suConfigPath);
    }

    /**
     * 读取application.yaml中关于su启停的配置
     */
    static private void loadYamlConfig(){
        msuYamlConfig = null;
    }

    static private void getServiceUnitInfo(File fileInfo){
        if (fileInfo != null && fileInfo.exists() && fileInfo.isDirectory()) {
            File[] files = fileInfo.listFiles((dir, name) -> dir.isDirectory() && name != null && name.equalsIgnoreCase("ServiceUnit.json"));

            //识别为su目录
            if (files != null && files.length > 0) {
                File file = files[0];
                //读取serviceunit.json内容
                String info = MsuConfigReader.readToBuffer(file.getAbsolutePath());
                if (info != null) {
                    Map<String,String> map = new HashMap<>();
                    map.put(MsuConfigVariable.SU_INFO,info);
                    map.put(MsuConfigVariable.SU_INFO_PATH,fileInfo.getAbsolutePath());
                    map.put(MsuConfigVariable.SU_INFO_APP,fileInfo.getParentFile().getName());
                    allSuInfo.add(map);
                    //存储suName
                    String su = MsuConfigReader.getSuFromJson(info).toLowerCase();
                    if(su!=null&&!allSu.contains(su))
                        allSu.add(su);
                }
            } else {
                //非su目录，继续递归，仅查找目录
                files = fileInfo.listFiles(pathname -> !pathname.isFile());
                if (files != null)
                    for (File file : files) {
                        getServiceUnitInfo(file);
                    }
            }
        }
    }



}
